package cn.fetosoft.woodpecker.controller;

import cn.fetosoft.woodpecker.core.event.TestPlanEvent;
import cn.fetosoft.woodpecker.enums.MessageType;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * 测试计划完成通知
 * @author guobingbing
 * @version 1.0
 * @wechat t_gbinb
 * @create 2021/6/25 9:17
 */
@Component
@ServerEndpoint("/auth/plan/notice/{userId}")
public class PlanResultNotice implements ApplicationListener<TestPlanEvent> {

	private static final Logger logger = LoggerFactory.getLogger(PlanResultNotice.class);
	private static final Map<String, Session> SESSION_MAP = new HashMap<>();

	@OnOpen
	public void connect(@PathParam("userId") String userId, Session session){
		SESSION_MAP.put(userId, session);
	}

	@OnMessage
	public void message(String message, Session session){
		try {
			JSONObject json = JSON.parseObject(message);
			if(MessageType.Heart.getName()==json.getInteger("type")){
				SocketMessage<JSON> resp = new SocketMessage<>(MessageType.Heart, "Pong - " + System.currentTimeMillis());
				session.getBasicRemote().sendText(resp.toString());
			}
		} catch (IOException e) {
			logger.error("message", e);
		}
	}

	@OnClose
	public void disconnect(Session session){
		this.destroy(session);
	}

	@OnError
	public void errorHandle(Throwable e, Session session){
		this.destroy(session);
		logger.error("onError", e);
	}

	private void destroy(Session session){
		if(session!=null && session.isOpen()){
			try {
				session.close();
			} catch (IOException e) {
				logger.error("destroy", e);
			}
		}
	}

	private void sendText(String userId, String text){
		Session session = SESSION_MAP.get(userId);
		if(session!=null && session.isOpen()){
			try {
				session.getBasicRemote().sendText(text);
			} catch (IOException e) {
				logger.error("sendText", e);
			}
		}
	}

	@Override
	public void onApplicationEvent(TestPlanEvent event) {
		JSONObject json = new JSONObject();
		json.put("name", event.getName());
		json.put("planId", event.getPlanId());
		json.put("testId", event.getTestId());
		json.put("success", event.isSuccess());
		json.put("errorMsg", event.getErrorMsg());
		SocketMessage<JSON> message = new SocketMessage<>(MessageType.TestComplete, "Test complete");
		message.setData(json);
		this.sendText(event.getUserId(), message.toString());
	}
}
